package com.spark.lola.service.sup.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.spark.lola.constant.CertificationStatus;
import com.spark.lola.entity.sup.*;
import com.spark.lola.feign.service.PortalServiceOpenApi;
import com.spark.lola.mapper.sup.*;
import com.spark.lola.request.CertificationApplyRequest;
import com.spark.lola.request.RegisterRequest;
import com.spark.lola.service.sup.IAccountInfoService;
import com.spark.lola.support.common.constant.CommonConstant;
import com.spark.lola.support.common.util.GeneratorUtil;
import com.spark.lola.support.common.util.NumberUtil;
import com.spark.lola.support.common.util.ResponseBean;
import com.spark.lola.support.core.param.MessageParam;
import com.spark.lola.support.mybatis.service.impl.BaseServiceImpl;
import com.spark.lola.support.wms.constant.RedisPrefix;
import com.spark.lola.support.wms.constant.SmsCodeConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author dengyejun
 * @since 2020-05-06
 */
@Service
public class AccountInfoServiceImpl extends BaseServiceImpl<AccountInfoMapper, AccountInfo> implements IAccountInfoService {
    private static final Logger logger = LoggerFactory.getLogger(AccountInfoServiceImpl.class);

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private RedisTemplate<String,String> systemRedis;

    @Autowired
    private PortalServiceOpenApi portalServiceOpenApi;

    @Autowired
    private AccountCertificationApplyMapper accountCertificationApplyMapper;
    @Autowired
    private AccountCertificationMapper accountCertificationMapper;
    @Autowired
    private SupplierInfoMapper supplierInfoMapper;
    @Autowired
    private BankInfoMapper bankInfoMapper;

    /**
     * 注册
     * @param request
     * @throws Exception
     */
    @Override
    public AccountInfo register(RegisterRequest request) throws Exception {
        logger.info("====用户【{}】注册===START===",request.getUsername());
        AccountInfo model = new AccountInfo();
        String smsKey = RedisPrefix.REGISTER_CODE+request.getMobile();
        if(!systemRedis.hasKey(smsKey)){
            throw new Exception("验证码已过期,请重新获取验证码!");
        }
        String code = systemRedis.opsForValue().get(smsKey);
        if(!code.equals(request.getCode())){
            throw new Exception("验证码不正确!");
        }
        model.setUsername(request.getUsername());
        model.setMobile(request.getMobile());
        if(!StringUtils.isEmpty(request.getPassword())) {
            model.setPassword(bCryptPasswordEncoder.encode(request.getPassword()));
        }
        if(baseMapper.insert(model)==0){
            throw new Exception("注册异常");
        }
        logger.info("====用户【{}】注册===END===",request.getUsername());
        return model;
    }

    /**
     * 获取注册验证码
     * @param username
     * @param mobile
     * @throws Exception
     */
    @Override
    public void registerCode(String username, String mobile) throws Exception {
        logger.info("====用户【{}】获取注册验证码===START===",username);
//        QueryWrapper<AccountInfo> query =new QueryWrapper<>();
//        query.eq("username",username);
//        query.or().eq("mobile",mobile);
//        if(baseMapper.selectCount(query)>0){
//            throw new Exception("用户名/手机已存在!");
//        }
        String randomCode = String.valueOf(GeneratorUtil.getRandomNumber(100000, 999999));
        logger.info("===验证码【{}】",randomCode);
        Map<String,String> map =new HashMap<>();
        map.put("code",randomCode);
        MessageParam param=new MessageParam(SmsCodeConstant.VERIFICATION_CODE,"+86"+mobile,map,null);
        ResponseBean responseBean = portalServiceOpenApi.sendMessage(param);
        if(responseBean.getCode()!=200){
            throw new Exception(responseBean.getMessage());
        }
        systemRedis.opsForValue().set(RedisPrefix.REGISTER_CODE+mobile,randomCode,10L, TimeUnit.MINUTES);
        logger.info("====用户【{}】获取注册验证码===END===",username);
    }

    @Override
    public Boolean checkCode(String mobile, String code) throws Exception {
        String key = RedisPrefix.CHECK_CODE + mobile;
        if(!systemRedis.hasKey(key)){
            throw  new Exception("请获取验证码!");
        }
        String checkCode = systemRedis.opsForValue().get(key);
        Boolean status = code.equals(checkCode);
        if(status){
            systemRedis.delete(key);
        }
        return status;
    }

    @Override
    public void createCheckCode(String mobile) throws Exception {
        String randomCode = String.valueOf(GeneratorUtil.getRandomNumber(100000, 999999));
        logger.info("===验证码【{}】", randomCode);
        Map<String, String> map = new HashMap<>();
        map.put("code", randomCode);
        MessageParam param = new MessageParam(SmsCodeConstant.VERIFICATION_CODE, "+86" + mobile, map, null);
        ResponseBean responseBean = portalServiceOpenApi.sendMessage(param);
        if (responseBean.getCode() != 200) {
            throw new Exception(responseBean.getMessage());
        }
        systemRedis.opsForValue().set(RedisPrefix.CHECK_CODE + mobile, randomCode, 10L, TimeUnit.MINUTES);
        logger.info("====手机【{}】获取证码【{}】===END===", mobile, randomCode);
    }

    /**
     * 认证失败
     * @param id
     * @param message
     */
    @Override
    public AccountCertificationApply authFail(Long id, String message) throws Exception {
        AccountCertificationApply model = accountCertificationApplyMapper.selectById(id);
        model.setStatus(CertificationStatus.FAILED);
        model.setRejectReason(message);
        if(accountCertificationApplyMapper.updateById(model)==0){
            logger.error("认证信息更新失败");
            throw new Exception("系统异常");
        }
        if(baseMapper.updateStatus(model.getAccountId(),model.getStatus())==0){
            logger.error("用户状态更新失败");
            throw new Exception("系统异常");
        }
        return model;
    }

    @Override
    public AccountCertificationApply authSuccess(Long id) throws Exception {
        logger.info("===用户【{}】认证通过===START===",id);
        AccountCertificationApply model = accountCertificationApplyMapper.selectById(id);
        AccountInfo accountInfo = baseMapper.selectById(model.getAccountId());
        model.setStatus(CertificationStatus.SUCCESS);
        logger.info("===更新认证申请状态");
        if(accountCertificationApplyMapper.updateById(model)==0){
            logger.error("认证信息更新失败");
            throw new Exception("系统异常");
        }
        logger.info("===存储用户认证信息");
        dealSaveCertifiaction(model);
        logger.info("===创建供应商基础信息");
        Long supplierId = dealSaveSupplier(model,accountInfo);
        logger.info("===保存付款信息");
        // dealSaveBank(model,supplierId);
        logger.info("===更新用户认证状态");
        accountInfo.setRealname(model.getRealname());
        accountInfo.setCertificationStatus(model.getStatus());
        accountInfo.setSupplierId(supplierId);
        if(baseMapper.updateById(accountInfo)==0){
            logger.error("用户状态更新失败");
            throw new Exception("系统异常");
        }
        logger.info("===用户【{}】认证通过===END===",id);
        return model;
    }

    /**
     * 存储用户认证信息
     * @param form
     */
    private void dealSaveCertifiaction(AccountCertificationApply form) throws Exception {
        AccountCertification model =new AccountCertification();
        BeanUtils.copyProperties(form, model);
        if(accountCertificationMapper.insert(model)==0){
            throw new Exception("用户认证信息保存失败");
        }
    }

    /**
     * 创建供应商基础信息
     * @param form
     * @param accountInfo
     * @throws Exception
     */
    private Long dealSaveSupplier(AccountCertificationApply form,AccountInfo accountInfo) throws Exception {
        SupplierInfo model =new SupplierInfo();
        if(!StringUtils.isEmpty(form.getCompanyName())) {
            model.setName(form.getCompanyName());
        }else{
            model.setName(form.getRealname());
        }
        model.setLicense(form.getLicense());
        model.setLinkman(form.getRealname());
        model.setMobile(accountInfo.getMobile());
        model.setUsed(CommonConstant.Y);
        model.setNo(String.valueOf(System.currentTimeMillis()));
        model.setSalesmanId(form.getSalesmanId());
        if(supplierInfoMapper.insert(model)==0){
            throw new Exception("供应商信息保存失败!");
        }
        return model.getId();
    }

    private void dealSaveBank(AccountCertificationApply form,Long supplierId) throws Exception {
        BankInfo model = new BankInfo();
        BeanUtils.copyProperties(form, model);
        if(bankInfoMapper.insert(model)==0){
            throw new Exception("付款信息保存失败!");
        }
    }

    /**
     * 提交认证
     * @param request
     */
    public void certificationApply(CertificationApplyRequest request) throws Exception {
        // 判断是否存在历史认证申请 有则删除
        QueryWrapper<AccountCertificationApply> query=new QueryWrapper<>();
        query.eq("account_id",request.getAccountId());
        if(accountCertificationApplyMapper.selectCount(query)>0){
            accountCertificationApplyMapper.delete(query);
        }

        AccountCertificationApply model =new AccountCertificationApply();
        BeanUtils.copyProperties(request, model);
        if(accountCertificationApplyMapper.insert(model)==0){
            throw new Exception("处理异常");
        }
        logger.info("===更新用户认证状态");
        if(baseMapper.updateStatus(model.getAccountId(),model.getStatus())==0){
            logger.error("用户状态更新失败");
            throw new Exception("系统异常");
        }
    }

}
